import React, {PureComponent} from "react"
import ModalComp from "../ModalItem/ModalComp";
import ButtonComp from "../ButtonComp"
import {Col, Row, List, Button, Radio} from "antd";
import {CameraOutlined, LeftOutlined} from "@ant-design/icons";
import classNames from "classnames"
import styles from "./index.less";
import { dateStr2Timestamp, getRandomKey } from 'jh-utils';
import {isEmpty, isFunction, findIndex, map, forEach} from "lodash-es";

let context = null;
let canvas = null;
let videoIns = null;
let type = "image/png";
export default  class PhotoUpload extends PureComponent {

    static defaultProps = {
        // visible:false,
    };

    canvasRef;
    videoRef;

    constructor(props) {
        super(props);
        this.state = {
            visible:false,
            isPlay:true,//记录播放视频
            fileObj:{},//保存图片
            errMessage:'',

            showVideos:false,
            videos:[],
            videoValue:'',
        };

    }
    componentDidMount(){
        window.addEventListener("resize", this.resize.bind(this));
    }
    componentWillMount() {
        window.removeEventListener("resize", this.resize.bind(this));
    }
    componentDidUpdate(prevProps, prevState){
        //|| (!prevState.isPlay && this.state.isPlay) || (!this.state.isPlay && prevState.isPlay)
        // if((!prevState.visible && this.state.visible) ){
        //     setTimeout(()=>{
        //         this.initVideo();
        //     },200)
        // }
    }
    resize(){
        // console.log('videoIns',videoIns.offsetWidth)
        if(canvas && videoIns) {
            canvas.width = videoIns.offsetWidth * 0.8;
        }
    };
    initVideo(){
        canvas = this.canvasRef;
        videoIns = this.videoRef;

        // console.log('canvas', canvas);

        if(canvas && videoIns) {
            context = canvas.getContext("2d");
            canvas.width = videoIns.offsetWidth * 0.85;
            // context.fillStyle="#FF0000";
            // context.fillRect(0,0,150,75);
            if (navigator && ((navigator.mediaDevices && navigator.mediaDevices.getUserMedia) ||
                navigator.getUserMedia ||
                navigator.webkitGetUserMedia ||
                navigator.mozGetUserMedia)){
                let { videos,videoValue  } = this.state;
                //调用用户媒体设备，访问摄像头

                let ind = findIndex(videos,item=>item.video.label === videoValue);
                if(ind > -1){
                    this.getUserMedia(videos[ind],this.success.bind(this),this.error.bind(this));
                }else{
                    this.getUserMedia({video:true},this.success.bind(this),this.error.bind(this));
                }

            } else {
                // alert("你的浏览器不支持访问用户媒体设备");
                this.setState({
                    errMessage:"你的浏览器不支持访问用户媒体设备",
                })
            }
        }
    };
    //访问用户媒体设备的兼容方法
    getUserMedia(constrains,success,error){
        if(navigator.mediaDevices.getUserMedia){
            //最新标准API
            navigator.mediaDevices.getUserMedia(constrains)
                .then(success)
                .catch(error);
        } else if (navigator.webkitGetUserMedia){
            //webkit内核浏览器
            navigator.webkitGetUserMedia(constrains)
                .then(success)
                .catch(error);
        } else if (navigator.mozGetUserMedia){
            //Firefox浏览器
            navigator.mozGetUserMedia(constrains)
                .then(success)
                .catch(error);
        } else if (navigator.getUserMedia){
            //旧版API
            navigator.getUserMedia(constrains)
                .then(success)
                .catch(error);
        }
    }

    /**
     * 查询摄像头信息，选择使用的摄像头
     * @param {*} deviceInfos
     */
    gotDevices(deviceInfos=[]){
        console.log('deviceInfos:',deviceInfos);
        let videos = [];
        forEach(deviceInfos,item=>{
            if(item.label && item.kind === "videoinput"){
                videos.push({
                    video:{
                        deviceId:item.deviceId,
                        label:item.label
                    },
                })
            }
        });
        let showVideos = false;
        if(videos.length>1){
            showVideos = true;
        }
        this.setState({
            videos,
            showVideos,
        },()=>{
            if(!showVideos){
                this.showInitVideo();
            }
        })

        //调用用户媒体设备，访问摄像头
        // this.getUserMedia(videos[0],this.success.bind(this),this.error.bind(this));

    }
    // 显示 video
    showInitVideo(){
        this.setState({showVideos:false,visible:true,fileObj:{},isPlay:true,errMessage:''},()=>{
            setTimeout(()=>{ this.initVideo() },50)
        });
    }
    handleError(e){}

    /**
     * 下载图片
     * @param data
     * @param filename
     */
    saveFile(data,filename){
        let link = document.createElementNS('http://www.w3.org/1999/xhtml', 'a');
        link.href = data;
        link.download = filename;
        let event = document.createEvent('MouseEvents');
        event.initMouseEvent('click', true, false, window, 0, 0, 0, 0, 0,
            false, false, false, false, 0, null);
        console.log("event",event);
        link.dispatchEvent(event);
    }
    //成功的回调函数
    success(stream){
        console.log("stream>>",stream,window.URL);
        //兼容webkit内核浏览器
        let CompatibleURL = window.URL || window.webkitURL;


        //将视频流设置为video元素的源
        // video.src = CompatibleURL.createObjectURL(stream);
        try {
            videoIns.srcObject = stream;
        } catch (error){
            videoIns.src = CompatibleURL.createObjectURL(stream);
        }
        //播放视频
        this.play();
    }
    //异常的回调函数
    error(error){
        // window.alert(error);
        let msg = "访问用户媒体设备失败："+error.name + error.message;
        console.log(msg);
        this.setState({errMessage:msg});
    }
    //播放视频
    play(){
        this.setState({
            errMessage:"",
        },()=>{
            videoIns.play();
        });

    }
    // 暂停视频
    pause(){
        videoIns.pause();
    }

    /**
     * 拍照 弹窗
     * */
    showModal(){
        // this.setState({visible:true,fileObj:{},isPlay:true,errMessage:''});
        if(navigator && (!navigator.mediaDevices || !navigator.mediaDevices.enumerateDevices)) {
            console.log('menumerateDevices is not supported!');
            //调用用户媒体设备，访问摄像头
            this.showInitVideo();
        }else {
            navigator.mediaDevices.enumerateDevices().then(this.gotDevices.bind(this)).catch(this.handleError.bind(this));
        }
    }

    /**
     * 拍照事件
     */
    photoClick(){
        this.setState({
            isPlay:false,
            fileObj:{},
        },()=>{
            //注册拍照按钮的单击事件
            //绘制画面
            if(context && videoIns){

                let width = canvas.width;
                let height = canvas.height;
                if(this.videoRef){
                    height = this.videoRef.offsetHeight
                }
                if(width < 600){
                    height = width * 4/5;
                }

                console.log('canvas.width',width,height);
                context.drawImage(videoIns,0,0,width,height);
                let imgData = canvas.toDataURL(type, 0.6);
                let fileObj = {
                    originFileObj:{
                        lastModified:dateStr2Timestamp(new Date()),
                        // lastModifiedDate:new Date(),
                        name:`${getRandomKey()}.png`,
                        type,
                        uid:getRandomKey(),
                        size:'',
                        webkitRelativePath:''
                    },
                    thumbUrl:imgData,
                    uid:getRandomKey(),
                };
                this.setState({fileObj});
                // console.log('imgData:',imgData);
                // this.saveFile(imgData,"test.png");
            }
            this.pause();
        });
    }

    /**
     * 继续拍照
     */
    keepPhoto(){
        this.saveFile();
        this.setState({
            isPlay:true,
            fileObj:{},
        },()=>{
            this.play();
        });
    }

    /**
     * 保存上传图片
     */
    saveFile(){
        let { fileObj } = this.state;

        let {onBeforeUploadCb} = this.props;
        !isEmpty(fileObj) && isFunction(onBeforeUploadCb) && onBeforeUploadCb(fileObj);
    }

    /**
     * 保存并返回
     */
    onOk(){
        this.saveFile();
        this.onCancel();
    }

    /**
     * 返回上一级
     */
    onCancel(){
        this.pause();
        this.setState({visible:false,fileObj:{},isPlay:true,errMessage:''})
    }

    /**
     * 取消本次拍照
     */
    cancel(){
        this.setState({fileObj:{},isPlay:true,errMessage:''},()=>{
            this.play();
        });
    }

    /**
     * radio选择 回调
     * @param e
     */
    onChange(e){
        let {target:{value} } = e;
        console.log('value:',value,e)
        this.setState({
            videoValue:value
        })
    }

    render(){
        let { visible, isPlay, fileObj, errMessage, videos,videoValue, showVideos } = this.state;

        let {boxHeight } = this.props;
        let height = boxHeight ? boxHeight : document.body.offsetHeight -300;
        let draggerStyle = {
            marginTop: 10, paddingRight: 10,
            height:height + 85
        };
        let cHeight  = (draggerStyle.height * 0.8);
        console.log("draggerStyle:",draggerStyle);

        let videoClass = "";
        let canvasClass = "";
        if(isPlay){
            videoClass = styles.show;
        }else
            canvasClass= styles.show;

        return (<>
            <div style={{overflow: 'hidden'}}
                 className={classNames('ant-upload', 'ant-upload-drag',styles.upload_drag)}
                 onClick={()=>{
                     this.showModal()
                 }}>
                <span className={classNames('ant-upload', 'ant-upload-btn')}>
                    <div className={'ant-upload-drag-container'}>
                        <p className="ant-upload-drag-icon">
                    <CameraOutlined />
                </p>
                <p className="ant-upload-text">请拍照完成上传</p>
                <p className="ant-upload-hint">支持单个或批量上传</p>
                    </div>
                </span>
            </div>
            <ModalComp
                visible={visible}
                width={'70%'}
                footer={null}
                mask={false}
                onCancel={this.onCancel.bind(this)}
                title={'拍照上传新文件'}
            >
                <Row style={draggerStyle}>
                    <Col span={24}>
                        <div className={styles.paneBtn} style={{paddingLeft: 0}}>
                            <Button onClick={this.onCancel.bind(this)}>
                                <LeftOutlined/>
                            </Button> 上传文件
                        </div>
                    </Col>
                    <Col span={24} style={{position:'relative',height:'80%',width:'100%'}}>

                        {
                            this.state.errMessage ?
                                <div style={{marginTop:cHeight/2}} className={styles.errStyle}>
                                    {this.state.errMessage}
                                </div> : (
                                    <>
                                        <video className={classNames(styles.videoClass,videoClass)} ref={(ref)=>{
                                            this.videoRef=ref;
                                        }}  autoPlay height={"100%"} width={"100%"}></video>
                                        <canvas className={classNames(styles.canvasClass,canvasClass)} ref={(ref)=>{
                                            this.canvasRef=ref;
                                        }} height={cHeight}></canvas>
                                    </>
                                )
                        }
                    </Col>
                    <Col span={24} className={styles.footerBtn}>
                        {
                            isPlay ? <ButtonComp
                                    type={"default"}
                                    style={{marginRight:8}}
                                    onClick={this.onCancel.bind(this)}
                                >
                                    返回
                                </ButtonComp> :
                                <ButtonComp
                                    type={"default"}
                                    style={{marginRight:8}}
                                    onClick={this.cancel.bind(this)}
                                >
                                    取消
                                </ButtonComp>
                        }
                        {
                            isPlay ? <ButtonComp
                                type={"primary"}
                                disabled={errMessage ? true : false}
                                style={{marginRight:8}}
                                onClick={this.photoClick.bind(this)}
                            >
                                点击拍照
                            </ButtonComp> :null
                        }
                        {
                            isPlay ? null : <ButtonComp
                                type={"primary"}
                                disabled={ isPlay || isEmpty(fileObj)}
                                onClick={this.keepPhoto.bind(this)}
                            >
                                确定
                            </ButtonComp>
                        }

                    </Col>
                </Row>

            </ModalComp>

            <ModalComp
                visible={showVideos}
                title={'请选择使用的设备'}
                width={"40%"}
                mask={false}
                style={{position:'relative',top:'25%'}}
                onCancel={()=>this.setState({showVideos:false})}
                onOk={()=>{
                    this.showInitVideo();
                }}
            >
                <div style={{height:draggerStyle.height/4}} className={styles.radioSty}>
                    <Radio.Group onChange={this.onChange.bind(this)} value={videoValue}>
                        {
                            map(videos,item=>{
                                return (
                                    <Radio style={{display:"block",height:"30px"}} value={item.video.label}>
                                        {item.video.label}
                                    </Radio>
                                )
                            })
                        }

                    </Radio.Group>
                </div>

            </ModalComp>
        </>)
    }
}